package com.itlong.cloud.operate.service.impl;

import com.itlong.cloud.POJO.DTO.operate.OperateAppFunctionGetPageDTO;
import com.itlong.cloud.POJO.PO.MiniProgramFunctionInfoPO;
import com.itlong.cloud.POJO.VO.app.AppFunctionInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.operate.dao.IOperateMiniProgramFunctionDao;
import com.itlong.cloud.operate.service.IOperateMiniProgramFunctionService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <desc>
 *      运营-套餐管理-小程序功能管理业务处理实现类
 * </desc>
 *
 * @createDate2020/3/23
 **/
@Service
public class OperateMiniProgramFunctionServiceImpl implements IOperateMiniProgramFunctionService {

    @Autowired
    private IOperateMiniProgramFunctionDao iOperateMiniProgramFunctionDao;

    /**
     * <desc>
     *      分页获取小程序功能列表
     * </desc>
     *
     * @param operateAppFunctionGetPageDTO 查询参数DTO
     * @return 小程序分页列表
     * @Author Zhu.yj
     * @createDate  2020/3/23
     */
    @Override
    public Page<MiniProgramFunctionInfoPO> getFunctionPage(OperateAppFunctionGetPageDTO operateAppFunctionGetPageDTO) throws Exception {
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(operateAppFunctionGetPageDTO);
        Page<MiniProgramFunctionInfoPO> page = new Page<>();
        page.getPage().setCurrentPage(operateAppFunctionGetPageDTO.getCurrentPage());
        page.getPage().setPageSize(operateAppFunctionGetPageDTO.getPageSize());
        params.put("startSlip",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        page.setRows(iOperateMiniProgramFunctionDao.getPage(params),iOperateMiniProgramFunctionDao.getPageCount(params));
        return page;
    }

    /**
     * <desc>
     *      更改小程序功能菜单信息
     * </desc>
     *
     * @param miniProgramFunctionInfoPO 功能实体
     * @return 受影响行数
     * @Author Zhu.yj
     * @createDate  2020/3/23
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer updateFunction(MiniProgramFunctionInfoPO miniProgramFunctionInfoPO) throws Exception {
        miniProgramFunctionInfoPO.setUpdateTime(new Date());
        return iOperateMiniProgramFunctionDao.update(SqlUtil.durableData(miniProgramFunctionInfoPO, PlatformConstants.TABLE_UPDATE));
    }

    /**
     * <desc>
     *      删除小程序功能id
     * </desc>
     *
     * @param miniFunctionIds 小程序功能id，多个逗号隔开
     * @return 受影响行数
     * @Author Zhu.yj
     * @createDate  2020/3/23
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer deleteFunction(String miniFunctionIds) throws Exception {
        //先删除功能套餐表中的数据

        //再删除功能表中包含miniFunctionIds的数据
        String[] miniFunctionId = StringHandlerUtil.splitString(miniFunctionIds);
        return iOperateMiniProgramFunctionDao.deleteFunction(miniFunctionId);
    }

    /**
     * <desc>
     *      禁用或启用小程序功能Id
     * </desc>
     *
     * @param miniFunctionId 小程序功能id
     * @param operType 操作类型 1启用 2禁用
     * @return 受影响行数
     * @Author Zhu.yj
     * @createDate  2020/3/23
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer banOrUse(String miniFunctionId, Integer operType) throws Exception {
        Map<String, Object> params =new HashMap<>();
        params.put("miniFunctionId",miniFunctionId);
        params.put("operType",operType);
        return iOperateMiniProgramFunctionDao.updateStatus(params);
    }

    /**
     * <desc>
     *      根据父功能id获取子节点列表
     * </desc>
     *
     * @param miniFunctionId 小程序功能id
     * @return 小程序功能节点列表
     * @Author Zhu.yj
     * @createDate  2020/3/23
     */
    @Override
    public List<AppFunctionInfoVO> getChilds(String miniFunctionId) throws Exception {
        List<AppFunctionInfoVO> appFunctionInfoVOS = iOperateMiniProgramFunctionDao.getChildByParent(miniFunctionId,1);
        appFunctionInfoVOS.forEach(child->{
            List<AppFunctionInfoVO> list = iOperateMiniProgramFunctionDao.getChildByParent(child.getAppFunctionId(),1);
            if (list != null && !list.isEmpty()) {
                child.setHaveChild("true");
            }
        });
        return appFunctionInfoVOS;
    }

    /**
     * <desc>
     *      通过套餐id获取小城功能列表
     * </desc>
     *
     * @param appPackageId 套餐id
     * @return
     * @Author Zhu.yj
     * @createDate  2020/3/24
     */
    @Override
    public List<AppFunctionInfoVO> getAllotFunction(String appPackageId) throws Exception {
        List<AppFunctionInfoVO> roots = iOperateMiniProgramFunctionDao.getChildByParent("0",2);
        List<String> miniPackageFunction = iOperateMiniProgramFunctionDao.getMiniPackageFunction(appPackageId);
        roots = recursionFunction(roots,miniPackageFunction);
        return roots;
    }

    /**
     * <desc>
     *      保存小程序功能菜单
     * </desc>
     *
     * @param miniProgramFunctionInfoPO 参数实体
     * @return
     * @Author Zhu.yj
     * @createDate  2020/3/24
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer save(MiniProgramFunctionInfoPO miniProgramFunctionInfoPO) throws Exception {
        miniProgramFunctionInfoPO.setMiniFunctionId(LogicIdUtil.bussinessId());
        miniProgramFunctionInfoPO.setCreateTime(new Date());
        return iOperateMiniProgramFunctionDao.save(SqlUtil.durableData(miniProgramFunctionInfoPO,PlatformConstants.TABLE_SAVE));
    }

    /**
     * <desc>
     *      获取小程序功能配置
     * </desc>
     *
     * @param projectId 项目id
     * @return
     * @Author Zhu.yj
     * @createDate  2020/3/26
     */
    @Override
    public List<MiniProgramFunctionInfoPO> getMiniConfig(String projectId) throws Exception {
        List<MiniProgramFunctionInfoPO> configList = iOperateMiniProgramFunctionDao.getMiniConfig(projectId);
        //查找项目是否绑定套餐，若未绑定套餐则返回全量功能
        if ((configList.size() == 0 || configList == null) && iOperateMiniProgramFunctionDao.getPackageCount(projectId) == 0) {
            return iOperateMiniProgramFunctionDao.getMiniFunctionList();
        }
        return configList;
    }

    /**
     * <desc>
     *      获取单个小程序信息
     * </desc>
     *
     * @param miniFunctionId 小程序功能id
     * @return
     * @Author Zhu.yj
     * @createDate  2020/4/1
     */
    @Override
    public MiniProgramFunctionInfoPO getOne(String miniFunctionId) throws Exception {
        return iOperateMiniProgramFunctionDao.getOne(miniFunctionId);
    }

    /**
     * <desc>
     *      递归获取所有节点 并查询套餐是否已有该节点
     * </desc>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2017/09/26
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<AppFunctionInfoVO> recursionFunction(List<AppFunctionInfoVO> roots, List<String> packageFunctions) {
        roots.forEach(child -> {
            List<AppFunctionInfoVO> list = iOperateMiniProgramFunctionDao.getChildByParent(child.getAppFunctionId(),2);
            //遍历roleFunctions查找第一个与child functionId相同的值，将child的haveAuth设为true
            if (packageFunctions.stream().filter(rf ->
                    rf.equals(child.getAppFunctionId())
            ).findFirst().isPresent()) {
                child.setHaveFunc("true");
            }
            if(child.getAllocation()==0){
                child.setHaveFunc("true");
            }
            if (list != null && !list.isEmpty()) {
                //遍历菜单节点与角色菜单判断是否已有
                list.forEach(function -> {
                    if (packageFunctions.stream().filter(rf ->
                            rf.equals(function.getAppFunctionId())
                    ).findFirst().isPresent()) {
                        function.setHaveFunc("true");
                    }
                    if(function.getAllocation()==0){
                        function.setHaveFunc("true");
                    }
                });
                child.setHaveChild("true");
                child.setChilds(this.recursionFunction(list, packageFunctions));
            }
        });
        return roots;
    }


}
